package com.jeeplus.modules.guide.web;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.jeeplus.common.json.AjaxJson;
import com.jeeplus.common.utils.DateUtils;
import com.jeeplus.common.utils.FileUtils;
import com.jeeplus.common.utils.StringUtils;
import com.jeeplus.config.properties.JeePlusProperites;
import com.jeeplus.modules.guide.service.PDFService;
import com.jeeplus.modules.guide.service.YmbcsMatterService;
import com.jeeplus.modules.sys.utils.FileKit;
import com.jeeplus.modules.work.queue.entity.ElectronicMaterialEntity;
import com.jeeplus.modules.work.queue.service.ElectronicMaterialService;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
import net.sf.json.JSONObject;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.*;

@Api(tags="高新服务pdf接口")
@RestController
@RequestMapping("/pdf")
@RequiredArgsConstructor
public class PDFSController {
    private static final Logger log = LoggerFactory.getLogger(PDFSController.class);
    private final PDFService pdfService;
    private final YmbcsMatterService ymbcsMatterService;
    private final ElectronicMaterialService electronicMaterialService;
    //经过测试,dpi为96,100,105,120,150,200中,105显示效果较为清晰,体积稳定,dpi越高图片体积越大,一般电脑显示分辨率为96
    public static final float DEFAULT_DPI = 120;
    //对接AppKeyValue
    @Value("${AppKeyValue}")
    private String AppKeyValue;
    /**
     * json数据转pdf
     *
     * @return
     */
    @PostMapping(value ="dateToPdf")
    public AjaxJson dateToPdf(@RequestHeader("AppKey") String AppKey, String data) throws IOException, DocumentException {
        if (!AppKeyValue.equals(AppKey)) return AjaxJson.error("AppKey is error!").put("code", 400);
        if(StringUtils.isNotBlank(data)){
            JSONObject json = JSONObject.fromObject(data);
            String openid = pdfService.findUserId(json.getJSONObject("tdr_cardid").getString("value"));
            if(StringUtils.isBlank(openid)) return AjaxJson.error("该用户未注册高馨办。请先注册。");
            String fileName = json.getJSONObject("tb_name").getString("value");
            PdfReader reader = new PdfReader(pdfService.findPdfByName(json.getJSONObject("tb_name").getString("value")));
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            PdfStamper ps = new PdfStamper(reader, bos);
            AcroFields s = ps.getAcroFields();
            /**
             * 使用中文字体 使用 AcroFields填充值的不需要在程序中设置字体，在模板文件中设置字体为中文字体 Adobe 宋体 std L
             */
            BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", false);
            /**
             * 设置编码格式
             */
            s.addSubstitutionFont(bfChinese);
            try{
                //text表单
                json = json.getJSONObject("data");
                s.setField("operatorAddr", json.getJSONObject("jycs").getString("value"));
                s.setField("operatorName", json.getJSONObject("jyzmc1").getString("value"));
                s.setField("operatorStreet", json.getJSONObject("jycsssjdb").getString("value"));
                s.setField("name", json.getJSONObject("sqr").getString("value"));
                s.setField("tell", json.getJSONObject("lxdh").getString("value"));
                s.setField("reson", json.getJSONObject("zxxkyy").getString("value"));
                s.setField("operatorCode", json.getJSONObject("xkzbh").getString("value"));
                s.setField("checkName", "");
                s.setField("deputyName", "");
                Calendar cal = Calendar.getInstance();
                cal.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(json.getJSONObject("sqrq").getString("value")));
                s.setField("year", String.valueOf(cal.get(Calendar.YEAR)));
                s.setField("month", String.valueOf(cal.get(Calendar.MONTH)+1));
                s.setField("day", String.valueOf(cal.get(Calendar.DAY_OF_MONTH)));
                // 如果为false那么生成的PDF文件还能编辑，一定要设为true
                ps.setFormFlattening(true);
                ps.close();
                //存放地址
                String fileDir = FileKit.getAttachmentDirYMBCSAll(openid);
                // 转存文件
                FileUtils.createDirectory(fileDir);
                String url = fileDir +  fileName + ".png";
                FileOutputStream fos = new FileOutputStream(url);
                //生成pdf
                //fos.write(bos.toByteArray());
                //pdf文件转图片
                fos.write(pdfToImage(bos.toByteArray()));
                reader.close();
                bos.close();
                fos.flush();
                fos.close();
                ElectronicMaterialEntity entity = new ElectronicMaterialEntity();
                entity.setLoginId(openid);
                entity.setCreateTime(DateUtils.getDateTime());
                entity.setStatus("0");
                entity.setOid("暂无数据");
                entity.setMaterialId("暂无数据");
                entity.setMaterialsType("png");
                entity.setElectronicMaterialsName(fileName);
                entity.setMaterialsUrl("/api/"+url.substring(url.indexOf("userfiles"),url.length()));
                entity.setSort("1");
                entity.setMaterialsItem("2");
                Integer integer = electronicMaterialService.upElectronicMaterial(entity);
                if(integer>=1){
                    return AjaxJson.success("操作成功！");
                }else{
                    return AjaxJson.error("保存异常。");
                }
            }catch (Exception e){
                return AjaxJson.error("json 填充数据异常");
            }
        }else{
            return AjaxJson.error("传参json数据为空");
        }
    }

    /**
     * 介绍信json数据转pdf
     *
     * @return
     */
    @PostMapping(value ="jsxToPdf")
    public AjaxJson jsxToPdf(String idcard,String tell,String name,String company,String number,String materialsName) throws IOException, DocumentException {
        if(StringUtils.isNotBlank(idcard)){
            String fileName = "介绍信或书面申请";
            String openid = pdfService.findUserId(idcard);
            if(StringUtils.isBlank(openid)) return AjaxJson.error("该用户未注册高馨办。请先注册。");
            PdfReader reader = new PdfReader(pdfService.findPdfByName("介绍信或书面申请"));
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            PdfStamper ps = new PdfStamper(reader, bos);
            AcroFields s = ps.getAcroFields();
            /**
             * 使用中文字体 使用 AcroFields填充值的不需要在程序中设置字体，在模板文件中设置字体为中文字体 Adobe 宋体 std L
             */
            BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", false);
            /**
             * 设置编码格式
             */
            s.addSubstitutionFont(bfChinese);
            try{
                //text表单
                s.setField("name", name);
                s.setField("idcard", idcard);
                s.setField("tell", tell);
                s.setField("number", number);
                s.setField("company", company);
                String dotime = DateUtils.getDate();
                s.setField("dotime", dotime);

                // 如果为false那么生成的PDF文件还能编辑，一定要设为true
                ps.setFormFlattening(true);
                ps.close();
                //存放地址
                String fileDir = FileKit.getjsxpdf(openid);
                // 转存文件
                FileUtils.createDirectory(fileDir);
                String url = fileDir +  fileName + ".png";
                FileOutputStream fos = new FileOutputStream(url);
                //生成pdf
                //fos.write(bos.toByteArray());
                //pdf文件转图片
                fos.write(pdfToImage(bos.toByteArray()));
                reader.close();
                bos.close();
                fos.flush();
                fos.close();
                ElectronicMaterialEntity entity = new ElectronicMaterialEntity();
                entity.setLoginId(openid);
                entity.setCreateTime(DateUtils.getDateTime());
                entity.setStatus("0");
                entity.setOid("2c98b0197a2fdce7017a410fe00b5a41");
                entity.setMaterialId("2c9392bf8b83b479018bf5deb1122435");
                entity.setMaterialsType("png");
                entity.setElectronicMaterialsName(materialsName);
                entity.setMaterialsUrl("/api/"+url.substring(url.indexOf("userfiles"),url.length()));
                entity.setSort("1");
                entity.setMaterialsItem("2");
                Integer integer = electronicMaterialService.upElectronicMaterial(entity);
                if(integer>=1){
                    this.pngtopdf(openid,idcard,tell,name,company,number,dotime,materialsName);
                    return AjaxJson.success("操作成功！");
                }else{
                    return AjaxJson.error("保存异常。");
                }
            }catch (Exception e){
                e.printStackTrace();
                return AjaxJson.error("json 填充数据异常");
            }
        }else{
            return AjaxJson.error("传参json数据为空");
        }
    }

    public void pngtopdf(String openid,String idcard,String tell,String name,String company,String number,String dotime,String materialsName) throws IOException, DocumentException {
        String fileName = "介绍信或书面申请";
        PdfReader reader = new PdfReader(pdfService.findPdfByName("介绍信或书面申请"));
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        PdfStamper ps = new PdfStamper(reader, bos);
        AcroFields s = ps.getAcroFields();
        /**
         * 使用中文字体 使用 AcroFields填充值的不需要在程序中设置字体，在模板文件中设置字体为中文字体 Adobe 宋体 std L
         */
        BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", false);
        /**
         * 设置编码格式
         */
        s.addSubstitutionFont(bfChinese);
        try{
            //text表单
            s.setField("name", name);
            s.setField("idcard", idcard);
            s.setField("tell", tell);
            s.setField("number", number);
            s.setField("company", company);
            s.setField("dotime", dotime);

            // 如果为false那么生成的PDF文件还能编辑，一定要设为true
            ps.setFormFlattening(true);
            ps.close();
            //存放地址
            String fileDir = FileKit.getjsxpdf(openid);
            // 转存文件
            FileUtils.createDirectory(fileDir);
            String url = fileDir +  fileName + ".pdf";
            FileOutputStream fos = new FileOutputStream(url);
            //生成pdf
            fos.write(bos.toByteArray());
            //pdf文件转图片
            //fos.write(pdfToImage(bos.toByteArray()));
            reader.close();
            bos.close();
            fos.flush();
            fos.close();
            ElectronicMaterialEntity entity = new ElectronicMaterialEntity();
            entity.setLoginId(openid);
            entity.setCreateTime(DateUtils.getDateTime());
            entity.setStatus("0");
            entity.setOid("2c98b0197a2fdce7017a410fe00b5a41");
            entity.setMaterialId("2c9392bf8b83b479018bf5deb1122435");
            entity.setMaterialsType("pdf");
            entity.setElectronicMaterialsName(materialsName);
            entity.setMaterialsUrl("/api/"+url.substring(url.indexOf("userfiles"),url.length()));
            entity.setSort("1");
            entity.setMaterialsItem("2");
            electronicMaterialService.upElectronicMaterial(entity);
        }catch (Exception e){
            log.error("pdf生成："+e.getMessage());
        }
    }



    /**
     * pdf文件转换成jpg图片流
     * @param pdfBytes 要转换的pdf文件的流
     */
    public static byte[] pdfToImage(byte[] pdfBytes) {
        try {
            PDDocument doc = PDDocument.load(pdfBytes);
            int pageCount = doc.getNumberOfPages();
            log.info("PDF转图片流，总页数:{}", pageCount);
            PDFRenderer pdfRenderer = new PDFRenderer(doc);
            // 不知道图片的宽和高，所以先定义个null
            BufferedImage pdfImage = null;
            // pdf有多少页
            int y = 0;
            List <BufferedImage> list = new ArrayList <>(pageCount);
            // 所有页高度综合
            int totalHeight = 0;
            if(pageCount > 0){
                for (int i = 0; i < pageCount; i++) {
                    // 每页pdf内容
                    BufferedImage bim = pdfRenderer.renderImageWithDPI(i, DEFAULT_DPI, ImageType.RGB);
                    totalHeight += bim.getHeight();
                    list.add(bim);
                }
            }
            for (BufferedImage bim : list) {
                // 如果是第一页需要初始化 BufferedImage
                if (Objects.isNull(pdfImage)) {
                    // 创建一个总高、总宽 的图片缓冲区
                    pdfImage = new BufferedImage(bim.getWidth(), totalHeight, BufferedImage.TYPE_INT_RGB);
                }
                // 将每页pdf画到总的pdfImage上,x坐标=0，y坐标=之前所有页的高度和，属于向下偏移
                pdfImage.getGraphics().drawImage(bim, 0, y, null);
                y += bim.getHeight();
            }
            doc.close();
            if(pdfImage != null){
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ImageIO.write(pdfImage, "jpg", baos);
                baos.flush();
                byte[] imageInByte = baos.toByteArray();
                log.info("PDF转图片流成功");
                return imageInByte;
            }
            return null;
        } catch (Exception e) {
            log.error("PDF转图片流失败：{}",e.getMessage());
            return null;
        }
    }
    /**
     * 获取pdf base64
     *
     * @return
     */
    @PostMapping(value ="getpdfbase64")
    public AjaxJson getpdfbase64(@RequestHeader("AppKey") String AppKey, String idcard){
        if (!AppKeyValue.equals(AppKey)) return AjaxJson.error("AppKey is error!").put("code", 400);
        String filePath = JeePlusProperites.newInstance().getUserfilesBaseDir()+ymbcsMatterService.findmaterialsUrl(idcard); // PDF文件路径
        filePath = filePath.replace("/api","");
        System.out.println(filePath);
        try {
            byte[] fileContent = Files.readAllBytes(Paths.get(filePath));
            String base64String = Base64.getEncoder().encodeToString(fileContent);
            return AjaxJson.success().put("data",base64String);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxJson.success().put("data",null);
        }
    }
}
